/* 
 * File:   InterpolacionLagrange.cpp
 * Author: Gina Ceron
 * 
 * Created on 10 de septiembre de 2011, 11:29 PM
 */

#include "InterpolacionLagrange.h"
#include <cstdio>
#include <iostream>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <cstdlib>

#define PI 3.14159265;

using namespace std;

InterpolacionLagrange::InterpolacionLagrange(){
    //Asigno variables "vitales"
    //
    this->ano=0;
    this->tam_ajuste=0;
    this->tam_ajusteRandom=0;
    this->tam_entrada=0;
    this->tam_aleatorios=0;
    
    //Array datos originales
    //
    array_datosX=NULL;
    array_datosY=NULL;
    //Array datos aleatorios
    //
    array_fdrand=NULL;
    array_xRandom= NULL;    
    //Array de coeficientes para construcción polinomios
    //
    array_coefBNewto= NULL;
    array_polysLagrng= NULL;
    
    array_xSelect=NULL;
    array_ySelect=NULL;
    tipoCalculo=false;
    flags=NULL;
    array_errorLagrng=NULL;
    array_errorNewtn=NULL;
}

InterpolacionLagrange::InterpolacionLagrange(int entrada, int nrandom, int ano, int ajuste, int ajusteRandom) {
    //Asigno variables "vitales"
    //
    this->ano=ano;
    this->tam_ajuste=ajuste;
    this->tam_ajusteRandom=ajusteRandom;
    this->tam_entrada=entrada;
    this->tam_aleatorios=nrandom;
    
    //Array datos originales
    //
    array_datosX=new double [tam_entrada];
    array_datosY=new double [tam_entrada];
    for(int i=0;i<tam_entrada;i++)
    {
        array_datosX[i]=0;
        array_datosY[i]=0;
    }
    
    //Array datos aleatorios
    //
    array_fdrand=new double [tam_aleatorios];
    array_xRandom= new double [tam_aleatorios];
    for(int i=0;i< tam_aleatorios;i++)
    {
        array_xRandom[i]=0.0;
        array_fdrand[i]=0.0;
    }
    
    //Array de coeficientes para construcción polinomios
    //
    array_coefBNewto= new double[tam_ajuste];
    array_polysLagrng= NULL;
    //Init de los arrays dependientes del tamaño del ajuste
    //    
    for(int i=0;i<tam_ajuste;i++)
    {
        array_coefBNewto[i]=0;
    }
    
    array_xSelect=NULL;
    array_ySelect=NULL;
    tipoCalculo=false;
    flags=NULL;
    array_errorLagrng=NULL;
    array_errorNewtn=NULL;
}

InterpolacionLagrange::~InterpolacionLagrange() {
    
    //Destruyo arreglos
    //
    delete array_datosX;
    delete array_datosY;
    array_datosX=NULL;
    array_datosY=NULL;
    
    //Destruyo arreglos aleatorios
    //
    delete array_fdrand;
    delete array_xRandom;
    array_fdrand=NULL;
    array_xRandom=NULL;
    
    //Destruyo arreglos de los resultados de interpolación
    //
    delete array_interpLgrng;
    delete array_interpNewtn;
    array_interpLgrng= NULL;
    array_interpNewtn= NULL;
    
    //Destruyo arreglo de elementos seleccionados
    //
    delete array_xSelect;
    delete array_ySelect;
    array_xSelect= NULL;
    array_ySelect= NULL;
    
    //Destruyo arreglo de coeficientes
    //
    delete array_coefBNewto;
    delete array_polysLagrng;
    array_coefBNewto=NULL;
    array_polysLagrng=NULL;
    //Destruyo arreglo de flags
    //
    delete flags;
    flags=NULL;
    //Desturyo arrelgo valores de los errores
    delete array_errorLagrng;
    delete array_errorNewtn;
    array_errorLagrng=NULL;
    array_errorNewtn=NULL;
}

void InterpolacionLagrange::setDatos(double x[], double y[], int entrada){
//    Destruyo array de ser necesario
//    
    if(array_datosX!=NULL || array_datosY!=NULL)
    {
        delete array_datosX;
        delete array_datosY;
        array_datosX=NULL;
        array_datosY=NULL;
    }
    array_datosX= new double [entrada];
    array_datosY= new double [entrada];
    
    this->tam_entrada=entrada;
    for(int i=0;i<tam_entrada;i++)
    {
        array_datosX[i]= x[i];
        array_datosY[i]= y[i];
    }
}

void InterpolacionLagrange::setDatosAleatorios(double xrand[], double yrand[], int tamAleat){
//    Destruyo array de ser necesario
//    
    if(array_xRandom!=NULL || array_fdrand!=NULL)
    {
        delete array_xRandom;
        delete array_fdrand;
        array_xRandom=NULL;
        array_fdrand=NULL;
    }

    array_xRandom=new double [tamAleat];
    array_fdrand=new double [tamAleat];
    
    this->tam_aleatorios=tamAleat;
    for(int i=0;i<tam_aleatorios;i++)
    {
        array_xRandom[i]= xrand[i];
        array_fdrand[i]= yrand[i];
    }
}

void InterpolacionLagrange::setSeleccion(double xSel[], double ySel[], int ajuste, bool flags[]){
//    Destruyo array de ser necesario
//    
    tam_ajuste=ajuste;
    if(array_xSelect!=NULL || array_ySelect!=NULL)
    {
        delete array_xSelect;
        delete array_ySelect;
        delete this->flags;
        array_xSelect=NULL;
        array_ySelect=NULL;
        this->flags=NULL;
    }
//Creo los arrays
//    
    array_xSelect=new double [ajuste];
    array_ySelect=new double [ajuste];
    this->flags=new bool[ajuste];
    this->tipoCalculo=false;
//    Instancio el array de los elementos seleccioados
//    
    for(int i=0;i<ajuste;i++)
    {
        array_xSelect[i]= xSel[i];
        array_ySelect[i]= ySel[i];
    }
//    Copio la bandera de flags
//    
    for(int j=0;j<tam_entrada;j++)
    {
        this->flags[j]=flags[j];
    }
}

Polinomio  InterpolacionLagrange::getPoly(const char* tipoPoly){
    string tipoPoli=tipoPoly;
    Polinomio respuesta;
    if(tipoPoli=="Lagrange")
    {
        respuesta=obj_polyLagrng;
    }else respuesta=obj_polyNewtn;
    return  respuesta;
}

void InterpolacionLagrange::leerArchivo(){
    FILE * ptr_archivo= fopen("datosPractica3.csv", "r+");
    int int_TmpX, int_TmpY;
    int cols=3;
    
    int_TmpX=0;
    int_TmpY=0;
    
    if(ptr_archivo!=NULL)
    {
        char str [100];
        char str2[100];
        int columnaAno;
        //Leo las primeras filas con caracteres de texto
        //
        for (int i =0; i<3;i++){
        
            fscanf(ptr_archivo,"\"%s ", str);
            fscanf(ptr_archivo,"%d", &int_TmpX);
            if(int_TmpX==ano) {
//                cout<<"Este es el año "<<int_TmpX<<endl;
                columnaAno=i;
//                cout<<"Contador Columna "<<i<<endl;
            }if (i==2)fscanf(ptr_archivo,"%s\n", str2);
        }
        fscanf(ptr_archivo,"%s",str);
        //Leo las filas con caracteres de numericos separadas por comas
        //
        for(int idFila=0;idFila<tam_entrada;idFila++)
        {
            for(int idCol=0;idCol<cols;idCol++)
            {
                fscanf(ptr_archivo,"%d;", &int_TmpX);
                fscanf(ptr_archivo,"%d;", &int_TmpY);
                if(idCol==columnaAno){
//                    cout<< int_TmpX<<", ";
                    array_datosX[idFila]=(double)int_TmpX;
//                    cout<< int_TmpY<<", ";
                    array_datosY[idFila]=(double)int_TmpY;
                }
            }
//            cout<<endl;
        }
    }
    else cout<<" No existe el archivo"<<endl;
}
//El parametro opción indica si es el primer punto o el segundo false para primero, true para segundo
//
void InterpolacionLagrange::escogerDatosInter(bool opcion ){
    int tamano=0; //tamaño del original
    int ajuste=0; //tamaño del ajuste
        double * array_datosTmpX;
        double * array_datosTmpY;
    
    tipoCalculo=opcion;
    //Selecciono parametros para la selcción deacuerdo a si es el punto aleatorio o no
    //
    if(tipoCalculo){
        
        tamano=tam_aleatorios;
        ajuste=tam_ajusteRandom;
    } else{
        tamano=tam_entrada;
        ajuste=tam_ajuste;
    }
    
    //creo arreglos e init
    //
    array_datosTmpX= new double [tamano];
    array_datosTmpY= new double [tamano];
    
    if(flags!=NULL)//   Reseteo las banderas de ser necesario
    {
        delete flags;
        flags=NULL;
    }
    
    if(array_xSelect!=NULL && array_ySelect!=NULL)//   Reseteo las arreglos de ser necesario
    {
        delete array_xSelect;
        delete array_ySelect;
        array_xSelect=NULL;
        array_ySelect=NULL;
    }
    flags= new bool[tamano];
    //Array de datos seleccionados
    //
    array_xSelect=new double [ajuste];
    array_ySelect= new double [ajuste];
    //Seteo los valores iniciales para los arreglos necesarios
    //
    for(int i=0;i<tamano;i++)
    {
        if(tipoCalculo){
            array_datosTmpX[i]=array_xRandom[i];
            array_datosTmpY[i]=array_fdrand[i];
            
        }else{
            array_datosTmpX[i]=array_datosX[i];
            array_datosTmpY[i]=array_datosY[i];
        }
        
        flags[i]=false;
    }
    //Escojo los datos
    //
    int factor=(int)ceil((double)tamano/(double)ajuste); //factor resultante de del tamaño y el ajuste


    bool yaEsta = true;
    int aleatorio=0;
    srand(time(NULL));
    //Escojo los a interpolar, segun el aleatorio
    //
    for(int idfils=0; idfils < ajuste; idfils++)
    {
        aleatorio=idfils*factor+idfils;

        if(aleatorio>=tamano)
        {
            while(yaEsta)
            {
                aleatorio = rand()%tamano;
                yaEsta=flags[aleatorio];             
            }
            yaEsta=true;
//            flags[aleatorio]=true;
        }
//        else
//        {
                flags[aleatorio]=true;
//        }
        array_xSelect[idfils]=array_datosTmpX[aleatorio];
        array_ySelect[idfils]=array_datosTmpY[aleatorio];
//        cout<<"Xsel: "<<array_xSelect[idfils]<<", Ysel: "<<array_ySelect[idfils]<<endl;
    }
    //Borro arreglos temporales
    //
    delete array_datosTmpX;
    delete array_datosTmpY;
    array_datosTmpX=NULL;
    array_datosTmpY=NULL;
}

void InterpolacionLagrange::ordenarDatosAInterpolar(){
//    Insertion
    int i, j;
    double tmpX, tmpY;
    int tam_ajuste=0;
    if(tipoCalculo)tam_ajuste=this->tam_ajusteRandom;
    else tam_ajuste=this->tam_ajuste;
    
    for(i=1;i<tam_ajuste;i++)
    {
        //Ordeno primer array
        //
        tmpX=array_xSelect[i];
        tmpY=array_ySelect[i];
        j=i-1;
        while(j >= 0)
        {
            if(array_xSelect[j] > tmpX)
            {
                array_xSelect[j+1] = array_xSelect[j];
                array_ySelect[j+1] = array_ySelect[j];
                j--;
            }else break;
        }
        array_xSelect[j+1] = tmpX;
        array_ySelect[j+1] = tmpY;
    }
    
//    cout<<"Tipo Calculo: "<<tipoCalculo<<endl;
//    for(int i=0;i<tam_ajuste;i++)
//    {
//        cout<<"xOrd: "<<array_xSelect[i]<<", yOrd: "<<array_ySelect[i]<<endl;
//    }
}

void InterpolacionLagrange::calcularCoeficientesNewton(){
    long double ** mat_difDiv=new long double * [tam_ajuste];
    
    double divisor, dividendo;
    
    for(int idFil=0;idFil<tam_ajuste;idFil++)
    {
        mat_difDiv[idFil]=new long double[tam_ajuste];
    }
    
    for(int idFil=0;idFil<tam_ajuste;idFil++)
    {
        for(int idCol=0;idCol<tam_ajuste;idCol++)
        {
            mat_difDiv[idFil][idCol]=0;
        }
    }
    
    for(int idFil=0;idFil<tam_ajuste;idFil++)
    {
        //Ingreso de datos x y y en matriz q guarda diferencias divididas para el 1er anho
        mat_difDiv[idFil][0]=(long double)array_ySelect[idFil];
    }
    for(int idCol=1;idCol<tam_ajuste;idCol++)
    {
        for(int idFil=0;idFil<tam_ajuste-idCol;idFil++)
        {
            dividendo=(mat_difDiv[idFil+1][idCol-1])-(mat_difDiv[idFil][idCol-1]);
            divisor=((long double)array_xSelect[idFil+idCol]-(long double)array_xSelect[idFil]);
            mat_difDiv[idFil][idCol]=dividendo/divisor;
        }
    }
    //Copio los coeficientes
    //
    for(int idCol=0;idCol<tam_ajuste;idCol++)
    {
        array_coefBNewto[idCol]=mat_difDiv[0][idCol];
    }
    
    //Borro la matriz
    //
    for(int idFil=0;idFil<tam_ajuste;idFil++) delete mat_difDiv[idFil];
    
    delete []mat_difDiv;
    
    mat_difDiv=NULL;    
}

void InterpolacionLagrange::calcularPolyLagrange(){
    Polinomio polyTmp1// Tendrá almacenado el polinomio resultante de la productoria, se utilizara como el temporal para la productoria
            ,polyTmp2/* Tendrá el polinomio creado a multiplicar*/
            ,polySumaParcial/*Se utiliza para almacenar la sumatoria*/;
    polySumaParcial.resetPolinomio();
    polySumaParcial.crearNodoPolinomio(0,0);
    int ajuste=0;
    if(tipoCalculo)
    {
        ajuste=tam_ajusteRandom;
    }
    else
    {
        ajuste=tam_ajuste;    
    }
    long double cte=0.0;
    for(int i=0;i<ajuste;i++)
    {
        polyTmp1.resetPolinomio();
        polyTmp1.crearNodoPolinomio(1.0,0);
        for(int j=0;j<ajuste;j++)
        {
            if(j==i)continue;
            else{
                polyTmp2.resetPolinomio();
                polyTmp2.crearNodoPolinomio(1.0,1);
                polyTmp2.crearNodoPolinomio(-1.0*array_xSelect[j], 0);
                cte=1.0/(long double)(array_xSelect[i]-array_xSelect[j]);
                polyTmp2=polyTmp2.const_mult_poly(cte);
                polyTmp1=polyTmp1.PolinomioXPolinomio(polyTmp1,polyTmp2);
            }
        }
        polyTmp1.const_mult_poly(array_ySelect[i]);
        //Sumo y_subi*L_subI
        //
        polySumaParcial=polySumaParcial.sumaPolinomio(polySumaParcial,polyTmp1);
    }
    
    obj_polyLagrng.resetPolinomio();
    obj_polyLagrng=polySumaParcial;  
}

void InterpolacionLagrange::evaluarDatos(){
//    obj_polyNewtn.resetPolinomio();
//    obj_polyNewtn.crearNodoPolinomio(1,1);
    int tamDatos=0; //Tamaño del conjunto de datos a evaluar
    int tamResults=0;    
    int idFilaEvaluacion=0;//Fila en la cual se está evaluando en el array de respuestas
    //Verifico si es para el punto uno o dos
    //
    if(tipoCalculo){//punto dos
        tamDatos=tam_aleatorios;
        tamResults=tam_aleatorios-tam_ajusteRandom;
    }
    else{//punto uno
        tamDatos=tam_entrada;
        tamResults=tam_entrada-tam_ajuste;
        array_interpNewtn=new double [tamResults];
    }
    
    //Empiezo a calcular los resultados
    //
    array_interpLgrng=new double [tamResults];
    long double xtmp=0;
    for(int i=0;i<tamDatos;i++)
    {
//        cout<<flags[i]<<", ";
        if(!flags[i]){
            if(tipoCalculo) xtmp=(long double)array_xRandom[i];
            else xtmp=(long double)array_datosX[i];
//            cout<<"idFila: "<<idFilaEvaluacion<<", "<<(double)obj_polyLagrng.evaluarPolinomio(xtmp)<<"\n";
            array_interpLgrng[idFilaEvaluacion]=(double)obj_polyLagrng.evaluarPolinomio(xtmp);
            if(!tipoCalculo) array_interpNewtn[idFilaEvaluacion]=(double)obj_polyNewtn.evaluarPolinomio(xtmp);
            idFilaEvaluacion++;
        }
    }
//    cout<<endl;
//    idFilaEvaluacion=0;
//    cout<<"Tipo Calculo: "<<tipoCalculo<<endl;
//    obj_polyLagrng.imprimirPolinomio();
//    cout<<endl;
//    for(int i=0;i<tamDatos;i++)
//    {
//        if(!flags[i]){
//            if(!tipoCalculo) cout<<"x: "<<array_datosX[i]<<"Lagrange(x): "<<array_interpLgrng[idFilaEvaluacion]<<
//                    ", Newton(x): "<<array_interpNewtn[idFilaEvaluacion]<<", f(x): "<<array_datosY[i]<<endl;
//            else cout<<"x: "<<array_xRandom[i]<<"Lagrange(x): "<<array_interpLgrng[idFilaEvaluacion]<<", f(x): "<<array_fdrand[i]<<endl;
//            idFilaEvaluacion++;
//        }
//    }
}

void InterpolacionLagrange::calcularPolyNewton(){
    Polinomio polyTmp1// Tendrá almacenado el polinomio resultante de la productoria, es temporal para la productoria
            ,polyTmp2/* Tendrá el polinomio creado a multiplicar*/
            ,polySumaParcial/*Se utiliza para almacenar la sumatoria*/;

    long double x_j;

    polySumaParcial.resetPolinomio();
    polySumaParcial.crearNodoPolinomio((long double)array_coefBNewto[0],0);//Valor inicial, el monomio b_0

    //For para la sumatoria
    for(int i=1;i<tam_ajuste;i++)
    {
        polyTmp1.resetPolinomio();
        polyTmp1.crearNodoPolinomio(1.0,0);

        //For para la productoria
        //
        for(int j=0; j< i;j++)
        {
            polyTmp2.resetPolinomio();
            polyTmp2.crearNodoPolinomio(1,1);
            x_j = array_datosX[j];
            polyTmp2.crearNodoPolinomio(-x_j,0);
            polyTmp1=polyTmp1.PolinomioXPolinomio(polyTmp1,polyTmp2);
            polyTmp2.resetPolinomio();
        }

        polyTmp1.const_mult_poly((long double)array_coefBNewto[i]);//multiplica la constante b por la productoria

        polySumaParcial=polySumaParcial.sumaPolinomio(polySumaParcial,polyTmp1);
//        if(i<tam_ajuste-1)polySumaParcial=polySumaParcial.sumaPolinomio(polySumaParcial,polyTmp1);//Suma polinomio de productoria y polinomio parcial
//          else obj_polyErrorNewtn=polyTmp1;        
    }

    obj_polyNewtn = polySumaParcial;
}

bool isInArray(double * array, int n,double val){
    for(int i=0;i<n;i++)
    {
        if(array[i]==val) return true;
    }
    return false;
}

bool isInArray(int * array, int n,int val){
    for(int i=0;i<n;i++)
    {
        if(array[i]==val)return true;
    }
    return false;
}

void InterpolacionLagrange::inicializarDatosAleatorios(){
    srand( time(NULL) );
    double decimal=0.0;
    bool esta=true;
    for(int i=0;i<tam_aleatorios;i++){
        while(esta)
        {
            decimal=4.0*(double)rand()/(double)RAND_MAX;
            decimal=decimal*PI;
            decimal=decimal*pow(-1.0, rand());
            esta=isInArray(array_xRandom,tam_aleatorios,decimal);
        }
        esta=true;
        array_xRandom[i]=decimal;
        array_fdrand[i]=sin(array_xRandom[i]);
//        cout<<"x: "<<array_xRandom[i]<<", sen(x): "<<array_fdrand[i]<<endl;
    }
}

void InterpolacionLagrange::escribirResultado1(){
    int contResul=0;
    FILE * output;
    output = fopen("resultadosPunto1.txt","w+");
    int x_entrada,y_esperado;
    double y_salidaL, y_salidaN;//Y salidas para Lagrange y Newton, respectivamente
    
    fprintf(output,"!!!!!Punto 1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    fprintf(output,"!!!!!Polinomios Lagrange y Newton 2006!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    fprintf(output,"X; Y; Pl(X);Rl(X); Pn(X); Rn(X); \n");
    for(int i=0;i<tam_entrada;i++)
    {
//        cout<<"entre al for q escribe el archivo 1 en i= "<<i<<endl;
        x_entrada=array_datosX[i];
        y_esperado=array_datosY[i];
//        cout<<"Valor de X: "<<x_entrada<<endl;
        if(!flags[i])
        {
            y_salidaL=array_interpLgrng[contResul];
            y_salidaN=array_interpNewtn[contResul];
//            cout<<"ErrorLagrange: "<<array_errorLagrng[contResul]<<", ErrorNewton: "<<array_errorNewtn[contResul]<<endl;
            fprintf(output,"%d; %d; %f; %f; %f; %f; \n", x_entrada, y_esperado, y_salidaL, array_errorLagrng[contResul], y_salidaN, array_errorNewtn[contResul]);
            contResul++;
        }
        else{
            y_salidaL=obj_polyLagrng.evaluarPolinomio((long double)x_entrada);
            y_salidaN=obj_polyNewtn.evaluarPolinomio((long double)x_entrada);
            fprintf(output,"!!!!!%d; %d; %f; %f; %f; %f; \n", x_entrada, y_esperado, y_salidaL, fabs(y_esperado-y_salidaL), y_salidaN, fabs(y_esperado-y_salidaN));
        }//Para este punto, dado que no conocemos f(x), el error se calcula como R=f(x)-p(x), donde f(x) es el valor de y de la tabla
     }
    contResul=0;
    fclose(output);
}


long double ffactorial(int n){
    long long int tmp=1;
    
    for(int val=1;val<=n;val++)
    {
        tmp*=val;
//        cout<<tmp<<", ";
    }
//    cout<<endl;
    
    return (long  double)tmp;
}

double derivadaNesimaSeno(int orden, double valor){
    double result;
    if((orden-1)%2==0) result=pow(-1.0,(orden-1)/2)*cos(valor);
    else result=pow(-1.0,orden/2)*sin(valor);
    return result;
}

void InterpolacionLagrange::construirError(){
    int tamErrors;
    int tamDatos;
//    Destruyo el array de ser necesario
//    
    if(array_errorLagrng!=NULL){
        delete array_errorNewtn;
        array_errorNewtn=NULL;
        delete array_errorLagrng;
        array_errorLagrng=NULL;
    }
//    asigno el tamaño del array errores dependiendo de la instancia del problema (punto que se esté trabajando)
//    
    if(!tipoCalculo)
    {
        tamDatos=tam_entrada;
        tamErrors=tam_entrada-tam_ajuste;
        array_errorNewtn=new double [tamErrors];
    }
    
    else{
        tamDatos=tam_aleatorios;
        tamErrors=tam_aleatorios-tam_ajusteRandom;
        
//                Construyo polinomio L(x)
//                
        Polinomio polyTmp2;
        Polinomio polyTmp1;
        polyTmp1.resetPolinomio();
        polyTmp1.crearNodoPolinomio(1.0,0);
        long double cte;
        cte=ffactorial(tam_ajusteRandom+1);
        cte=1.0/cte;
//        cout<<"CTE: "<<cte<<endl;

        double puntoMedio=0;
        for(int j=0;j<tam_ajusteRandom;j++)
        {
            polyTmp2.resetPolinomio();
            polyTmp2.crearNodoPolinomio(1.0,1);
            polyTmp2.crearNodoPolinomio(-1.0*array_xSelect[j], 0);
            polyTmp1=polyTmp1.PolinomioXPolinomio(polyTmp1,polyTmp2);
        }
        polyTmp1=polyTmp1.const_mult_poly(cte);
        //multiplico por la evaluación de la derivada de orden n+1 en el punto 
        //
        cte=derivadaNesimaSeno(tam_ajusteRandom+1,puntoMedio);
//        cout<<"Cte: "<<cte<<endl;
        obj_polyErrorLagrng=polyTmp1.const_mult_poly((long double)cte);
    }
    
    //Llenoarray de error
    //
    array_errorLagrng=new double [tamErrors];
    int idFila=0;
    for(int i=0;i<tamDatos;i++)
    {
        if(!flags[i])
        {
            if(!tipoCalculo){
                array_errorNewtn[idFila]=fabs(array_datosY[i]-array_interpNewtn[idFila]);
                array_errorLagrng[idFila]=fabs(array_datosY[i]-array_interpLgrng[idFila]);
//                cout<<"ErrorNewton: "<<array_errorNewtn[idFila]<<", ErrorLagrange: "<<array_errorLagrng[idFila]<<endl;
            }
            else{
                double derivada=derivadaNesimaSeno(tam_ajusteRandom+1,array_xRandom[i]);
//                cout<<"Derivada: "<<derivada<<endl;
                array_errorLagrng[idFila]=fabs(obj_polyErrorLagrng.evaluarPolinomio(array_xRandom[i])*derivada);
//                cout<<"X: "<<array_xRandom[i]<<", Y: "<<array_fdrand[i]<<", L(x): "<<array_interpLgrng[idFila]<<", ErrorLagrange: "<<array_errorLagrng[idFila]<<endl;
            }
            idFila++;
        }
    }
}

void InterpolacionLagrange::escribirResultado2(){
    int contResul=0;
    FILE * output;
    output = fopen("resultadosPunto2.txt","w+");
    double x_entrada,y_esperado;
    double y_salidaL;
    
    fprintf(output,"!!!!!Punto 2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    fprintf(output,"!!!!!Polinomio Lagrange Seno 2006!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    fprintf(output,"X; Y; Pl(X);Rl(X); \n");
    for(int i=0;i<tam_aleatorios;i++)
    {
        x_entrada=array_xRandom[i];
        y_esperado=array_fdrand[i];
        if(!flags[i])
        {
            y_salidaL=array_interpLgrng[contResul];
            fprintf(output,"%f; %f; %f; %f; \n", x_entrada, y_esperado, y_salidaL, array_errorLagrng[contResul]);
            contResul++;
        }
        else{
            y_salidaL=obj_polyLagrng.evaluarPolinomio(x_entrada);
            fprintf(output,"!!!!!%f; %f; %f; %f; \n", x_entrada, y_esperado, y_salidaL, 0.0);
        }
     }
    fclose(output);
}